home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre2.z / postgre2 / ref / postquel / defineFunction < prev    next >
Encoding:
Text File  |  1992-08-27  |  13.8 KB  |  499 lines

  1. .\" XXX standard disclaimer belongs here....
  2. .\" $Header: /private/postgres/ref/postquel/RCS/defineFunction,v 1.6 1992/07/14 05:54:17 ptong Exp $
  3. .SP "DEFINE FUNCTION" COMMANDS 7/9/92
  4. .XA 2 "Define Function"
  5. .uh "NAME"
  6. .lp
  7. define function \*- define a new function
  8. .uh "SYNOPSIS"
  9. .lp
  10. .(l
  11. \fBdefine function\fP function_name \fB(\fP
  12.           \fBlanguage =\fP {"c" | "postquel"}\fB,\fP
  13.           \fBreturntype =\fP type-r
  14.           [ \fB, percall_cpu =\fP \fB"costly\fR{\fB!\fR*}\fB"\fR ]
  15.           [ \fB, perbyte_cpu =\fP \fB"costly\fR{\fB!\fR*}\fB"\fR ]
  16.           [ \fB, outin_ratio = \fP percentage]
  17.           [ \fB, byte_pct = \fP percentage]
  18.         \fB)\fP
  19.     \fBarg is (\fP type-1  { \fB,\fP type-n } \fB)\fP
  20.     \fBas\fP {"/full/path/filename.o" | "list-of-postquel-queries"}
  21. .)l
  22. .uh "DESCRIPTION"
  23. .lp
  24. With this command, a \*(PP user can register a function with \*(PP.
  25. Subsequently, this user is treated as the owner of the function.
  26. .lp
  27. When defining the function, the input data types,
  28. .i type-1 ,
  29. .i type-2 ,
  30. \&...,
  31. .i type-n ,
  32. and the return data type,
  33. .i type-r
  34. must be specified,
  35. along with the language, which may be
  36. .i 
  37. "c"
  38. .r
  39. or
  40. .i
  41. "postquel".
  42. .r
  43. The input types may be base or complex types.  The output type may be
  44. specified as a base type, complex type, or 
  45. .i "setof <type>".
  46. The 
  47. .i setof
  48. modifier indicates that the function will return a set of items,
  49. rather than a single item.
  50. The
  51. .i as
  52. clause of the command is treated differently for C and \*(PQ
  53. functions, as explained below.
  54. .lp
  55. .uh "C FUNCTIONS"
  56. .lp
  57. Functions written in C can be defined to \*(PP, which will
  58. dynamically load them into its address space.  The loading happens
  59. either via the \fBload\fP command, or automatically the
  60. first time the function is necessary for execution. Repeated execution
  61. of a function will cause negligible additional overhead, as the
  62. function will remain in a main memory cache.
  63. .lp
  64. The 
  65. .i percall_cpu,
  66. .i perbyte_cpu,
  67. .i outin_ratio,
  68. and
  69. .i byte_pct
  70. flags are provided for C functions to give a rough estimate of the
  71. function's running time, allowing the query optimizer to postpone applying
  72. expensive functions used in a query's
  73. .i where
  74. clause.  The 
  75. .i percall_cpu
  76. flag captures the overhead of the function's invocation (regardless of
  77. input size), while the 
  78. .i perbyte_cpu
  79. flag captures the sensitivity of the function's running time to the
  80. size of its inputs.  The magnitude of these two parameters is
  81. determined by the number of exclamation points appearing after the
  82. word
  83. .i costly: 
  84. specifically, each exclamation point can be thought of as another
  85. order of magnitude in cost, i.e.,
  86. .i "cost = 10\s-2\unumber-of-exclamation-points\d\s0."
  87. The default value for 
  88. .i percall_cpu
  89. and
  90. .i perbyte_cpu
  91. is 0.  Examples of reasonable cost values may be found in the system catalog
  92. .i pg_proc;
  93. most simple functions on base types have costs of 0.
  94. .lp
  95. The
  96. .i outin_ratio
  97. is provided for functions which return variable-length types, such as
  98. .i text
  99. or
  100. .i bytea.
  101. It should be set to the size of the function's output as a percentage
  102. of the size of the input.  For example, a function which compresses
  103. its operands by 2 should have
  104. .i "outin_ratio = 50."
  105. The default value is 100.
  106. .lp
  107. The
  108. .i byte_pct
  109. flag should be set to the percentage of the bytes of the arguments
  110. that actually need to be examined in order to compute the function.
  111. This flag is particularly useful for functions which generally take a
  112. large object as an argument, but only examine a small fixed portion of
  113. the object.  The default value is 100.
  114. .lp
  115. The body of a C function following 
  116. .i as
  117. should be the FULL PATH of the object code (.o file) for the function,
  118. bracketed by quotation marks.  (\*(PP will not compile a function
  119. automatically -- it must be compiled before it is used in a define
  120. function command.)
  121. .lp
  122. C functions with base type arguments can be written in a
  123. straightforward fashion.  The C equivalents of built-in \*(PP types
  124. are accessible in a C file if 
  125. .ft C
  126. $POSTGRESHOME/src/lib/H/utils/builtins.h
  127. .ft
  128. is included as a header file.  This can be achieved by having
  129. .(l
  130. .ft C
  131. #include <utils/builtins.h>
  132. .ft
  133. .)l
  134. at the top of the C source file and by compiling all C files with the
  135. following include options:
  136. .(l
  137. .ft C
  138.  -I$POSTGRESHOME/src/lib/H
  139.  -I$POSTGRESHOME/src/port/$PORTNAME
  140.  -I$POSTGRESHOME/O/lib/H
  141. .ft
  142. .)l
  143. before any ".c" programs in the "cc" command line, e.g.:
  144. .(l
  145. .ft C
  146. cc -I$POSTGRESHOME/src/lib/H \\
  147.         -I$POSTGRESHOME/src/port/$PORTNAME \\
  148.         -I$POSTGRESHOME/O/lib/H \\
  149.         -c progname.c
  150. .ft
  151. .)l
  152. The directory
  153. .ft C
  154. $POSTGRESHOME/O/lib/H
  155. .ft
  156. contains "tags.h", which is generated in the
  157. build process.  The directory
  158. .ft C
  159. $POSTGRESHOME/src/port/$PORTNAME
  160. .ft
  161. contains
  162. "machine.h".  Typical values for PORTNAME are sunos4 and ultrix4.
  163. .lp
  164. The convention for passing arguments to and from the user's C functions is
  165. to use pass-by-value for data types that are 32 bits (4 bytes) or
  166. smaller, and pass-by-reference for data types that require more than 32 bits.
  167. The following table gives the C type required for parameters in the C
  168. functions that will be loaded into \*(PP.  The "Defined In" column
  169. gives the actual header file (in the
  170. .ft C
  171. $POSTGRESHOME/src/lib/H
  172. .ft
  173. directory) that the equivalent
  174. C type is defined.  However, if you include "utils/builtins.h", these
  175. files will automatically be included.
  176. .uh "Equivalent C Types for Built-In \*(PP Types"
  177. .lp
  178. .TS
  179. center;
  180. l l l
  181. l l l.
  182. \fBBuilt-In Type\fP    \fBC Type\fP    \fBDefined In\fP
  183. _
  184. abstime     AbsoluteTime    utils/nabstime.h
  185. bool    bool    tmp/c.h
  186. box    (BOX *)     utils/geo-decls.h
  187. bytea    (bytea *)    tmp/postgres.h
  188. char    char    N/A
  189. char16    Char16 or (char16 *)    tmp/postgres.h
  190. cid    CID    tmp/postgres.h
  191. int2    int2    tmp/postgres.h
  192. int28    (int28 *)    tmp/postgres.h
  193. int4    int4    tmp/postgres.h
  194. float4    float32 or (float4 *)    tmp/c.h or tmp/postgres.h
  195. float8    float64 or (float8 *)    tmp/c.h or tmp/postgres.h
  196. lseg    (LSEG *)    tmp/geo-decls.h
  197. oid    oid    tmp/postgres.h
  198. oid8    (oid8 *)    tmp/postgres.h
  199. path    (PATH *)    utils/geo-decls.h
  200. point    (POINT *)    utils/geo-decls.h
  201. regproc     regproc or REGPROC    tmp/postgres.h
  202. reltime     RELTIME     tmp/postgres.h
  203. text    (text *)    tmp/postgres.h
  204. tid    ItemPointer    storage/itemptr.h
  205. tinterval    TimeInterval    tmp/nabstime.h
  206. uint2    uint16    tmp/c.h
  207. uint4    uint32    tmp/c.h
  208. xid    (XID *)     tmp/postgres.h
  209. .TE
  210. .lp
  211.  
  212. Complex arguments to C functions are passed into the C function as a
  213. special C type, TUPLE, defined in
  214. .ft C
  215. $POSTGRESHOME/src/lib/H/tmp/libpq-fe.h.
  216. .ft
  217. Given a variable t of this
  218. type, the C function may extract attributes from the function
  219. using the function call:
  220. .(l
  221. .ft C
  222. GetAttributeByName(t, "fieldname", &isnull)
  223. .ft
  224. .)l
  225. where 
  226. .i isnull
  227. is a pointer to a bool, which the function sets to \fItrue\fP if the
  228. field is null.  The result of this function should be cast
  229. appropriately as shown in the examples below.
  230. .lp
  231. .uh "POSTQUEL FUNCTIONS"
  232. .lp
  233. \*(PQ functions execute an arbitrary list of \*(PQ queries,
  234. returning the results of the last query in the list.  \*(PQ
  235. functions in general return sets.  If their returntype is not
  236. specified as a \fIsetof\fP, then an arbitrary element of the last
  237. query's result will be returned.  The expensive function parameters
  238. .i percall_cpu,
  239. .i perbyte_cpu,
  240. .i outin_ratio,
  241. and
  242. .i byte_pct
  243. are not used for \*(PQ functions; their costs are determined
  244. dynamically by the planner.
  245. .lp
  246. The body of a \*(PQ function following
  247. .i as
  248. should be a list of queries separated by
  249. whitespace characters and bracketed within quotation marks.  Note that
  250. quotation marks used in the queries must be escaped, by preceding them
  251. with two backslashes (i.e. \\").
  252. .lp
  253. Arguments to the \*(PQ function may be referenced in the queries
  254. using a $n syntax: $1 refers to the first argument, $2 to the second,
  255. and so on.  If an argument is complex, then a "dot" notation may be used to
  256. access attributes of the argument (e.g. $1.emp), or to invoke
  257. functions via a nested dot syntax.  
  258. .lp
  259. .uh "EXAMPLES: C Functions"
  260. .lp
  261. The following command defines a C function, overpaid, of two basetype
  262. arguments.
  263. .(l
  264. .ft C
  265. define function overpaid
  266.         (language = "c", returntype = bool)
  267.         arg is (float8, int4)
  268.         as "/usr/postgres/src/adt/overpaid.o"
  269. .ft
  270. .)l
  271. The C file "overpaid.c" might look something like:
  272. .(l
  273. .ft C
  274. #include <utils/builtins.h>
  275.  
  276. bool overpaid(salary, age)
  277.         float8 *salary;
  278.         int4    age;
  279. {
  280.         if (*salary > 200000.00)
  281.                 return(TRUE);
  282.         if ((age < 30) && (*salary > 100000.00))
  283.                 return(TRUE);
  284.         return(FALSE)
  285. }
  286. .ft
  287. .)l
  288. The overpaid function can be used in a query, e.g:
  289. .(l
  290. .ft C
  291. retrieve (EMP.name)
  292.     where overpaid(EMP.salary, EMP.age)
  293. .ft
  294. .)l
  295. .lp
  296. One can also write this as a function of a single argument of type
  297. EMP:
  298. .(l
  299. .ft C
  300. define function overpaid_2
  301.         (language = "c", returntype = bool)
  302.         arg is (EMP)
  303.         as "/usr/postgres/src/adt/overpaid_2.o"
  304. .ft
  305. .)l
  306. The following query is now accepted:
  307. .(l
  308. .ft C
  309. retrieve (EMP.name) where overpaid_2(EMP) 
  310. .ft
  311. .)l
  312. In this case, in the body of the overpaid_2 function, the fields in the EMP
  313. record must be extracted.  The C file "overpaid_2.c" might look
  314. something like:
  315. .(l
  316. .ft C
  317. #include <utils/builtins.h>
  318. #include <tmp/libpq-fe.h>
  319.  
  320. bool overpaid_2(t)
  321. TUPLE t;
  322. {
  323.     float8 *salary;
  324.     int4    age;
  325.     bool    salnull, agenull;
  326.  
  327.     salary = (float8 *)GetAttributeByName(t, "salary",
  328.                                           &salnull);
  329.     age = (int4)GetAttributeByName(t, "age", &agenull);
  330.     if (!salnull && *salary > 200000.00)
  331.         return(TRUE);
  332.     if (!agenull && (age<30) && (*salary > 100000.00))
  333.         return(TRUE);
  334.     return(FALSE)
  335. }
  336. .ft
  337. .)l
  338. .lp
  339. .uh "EXAMPLES: \*(PQ Functions"
  340. .lp
  341. To illustrate a simple \*(PQ function, consider the following,
  342. which might be used to debit a bank account:
  343. .(l
  344. .ft C
  345. define function TP1
  346.         (language = "postquel", returntype = int4)
  347.         arg is (int4, float8)
  348.         as "replace BANK (balance = BANK.balance - $2)
  349.               where BANK.accountno = $1
  350.             retrieve(x = 1)"
  351. .ft
  352. .)l
  353. A user could execute this function to debit account 17 by $100.00 as follows:
  354. .(l
  355. .ft C
  356. retrieve (x = TP1( 17,100.0))
  357. .ft
  358. .)l
  359. .lp
  360. The following more interesting examples take a single argument of type
  361. EMP, and retrieve multiple results:
  362. .(l
  363. .ft C
  364. define function hobbies
  365.     (language = "postquel", returntype = setof HOBBIES)
  366.     arg is (EMP)
  367.     as "retrieve (HOBBIES.all)
  368.           where $1.name = HOBBIES.person"
  369.  
  370. define function children
  371.     (language = "postquel", returntype = setof KIDS)
  372.     arg is (EMP)
  373.     as "retrieve (KIDS.all)
  374.           where $1.name = KIDS.dad
  375.              or $1.name = KIDS.mom"
  376. .ft
  377. .)l
  378. .lp
  379. Then the following query retrieves overpaid employees, their hobbies, and
  380. their children:
  381. .lp
  382. .(l
  383. .ft C
  384. retrieve (name=name(EMP), hobby=name(hobbies(EMP)),
  385.     kid=name(children(EMP)))
  386.     where overpaid_2(EMP)
  387. .ft
  388. .)l
  389. Note that attributes can be projected using function syntax (e.g.
  390. name(EMP)), as well as the traditional dot syntax (e.g. EMP.name).
  391. .lp
  392. An equivalent expression of the previous query is:
  393. .(l
  394. .ft C
  395. retrieve (EMP.name, hobby=EMP.hobbies.name,
  396.     kid=EMP.children.name)
  397.     where overpaid_2(EMP)
  398. .ft
  399. .)l
  400. This "nested dot" notation for functions can be used to cascade
  401. functions of single arguments.  Note that the function after a dot
  402. must have only one argument, of the type returned by the function
  403. before the dot.
  404. .lp
  405. \*(PP 
  406. .i flattens
  407. the target list of the queries above.  That is, it produces the cross-product
  408. of the hobbies and the children of the employees.  For example, given
  409. the schema:
  410. .(l
  411. .ft C
  412. create BANK (accountno = int4, balance = float8) 
  413. append BANK (accountno = 17,
  414.              balance = "10000.00"::float8)
  415. create EMP (name = char16, salary = float8,
  416.             dept = char16, age = int4)
  417. create HOBBIES (name = char16, person = char16) 
  418. create KIDS (name = char16, dad = char16, mom = char16) 
  419. append EMP (name = "joey", salary = "100000.01"::float8,
  420.             dept = "toy", age = 24) 
  421. append EMP (name = "jeff", salary = "100000.01"::float8,
  422.             dept = "shoe", age = 23)
  423. append EMP (name = "wei", salary = "100000"::float8,
  424.             dept = "tv", age = 30) 
  425. append EMP (name = "mike", salary = "500000"::float8,
  426.             dept = "appliances", age = 30) 
  427. append HOBBIES (name = "biking", person = "jeff" ) 
  428. append HOBBIES (name = "jamming", person = "joey" ) 
  429. append HOBBIES (name = "basketball", person = "wei") 
  430. append HOBBIES (name = "swimming", person = "mike") 
  431. append HOBBIES (name = "philately", person = "mike") 
  432. append KIDS (name = "matthew", dad = "mike",
  433.              mom = "teresa")
  434. append KIDS (name = "calvin", dad = "mike",
  435.              mom = "teresa")
  436. .ft
  437. .)l
  438. .sp
  439. the query above returns
  440. .lp
  441. .ft C
  442. .TS
  443. center;
  444. l l l
  445. l l l.
  446. name    hobby    kid
  447. _
  448. jeff    biking    (null)
  449. joey    jamming    (null)
  450. mike    swimming    matthew
  451. mike    philately    matthew
  452. mike    swimming    calvin
  453. mike    philately    calvin
  454. .TE
  455. .ft
  456. .lp
  457. Note that flattening preserves the name and hobby fields even when the kid
  458. field is null.
  459. .lp
  460. .uh "SEE ALSO"
  461. .lp
  462. information(unix), load(commands), remove function(commands).
  463. .lp
  464. .uh "NOTES"
  465. .lp
  466. The 
  467. .i percall_cpu
  468. and
  469. .i perbyte_cpu
  470. flags can take integers surrounded by quotes instead of the 
  471. .i """costly{!*}"""
  472. syntax
  473. described above.  This allows a finer grain of distinction between
  474. function costs, but is not encouraged since such distinctions are
  475. difficult to estimate accurately.
  476. .lp
  477. On Ultrix, all .o files that \*(PP is expected to load dynamically must
  478. be compiled under \f2cc\fP with the
  479. .ft C
  480. "-G 0"
  481. .ft
  482. option turned on.
  483. .uh "RESTRICTIONS"
  484. .lp
  485. The name of the C function must be a legal C function name, and the name of
  486. the function in C code must be exactly the same as the name used in
  487. define function.
  488. .lp
  489. .uh "BUGS"
  490. .lp
  491. Function names must be unique per database, except for the fact that
  492. there may be attributes of the same name as a function.  In the case
  493. that a there is an ambiguity between a function on a complex type and
  494. an attribute of the complex type, the attribute will always be used.
  495. .lp
  496. C functions cannot return a set of values.
  497. .lp
  498. The dynamic loader for DECstation Ultrix has exceedingly bad performance.
  499.